home *** CD-ROM | disk | FTP | other *** search
- /* proc.c */
-
- /* JOVE/MSDOS. K. Mitchum 1/85 */
- /* Modifications for personal use only. */
- /* original code J. Payne LSRHS 5/83 */
- /* Ken Mitchum */
- /* University of Pittsburgh */
- /* Decision Systems Laboratory */
-
- /*
- Jonathan Payne at Lincoln-Sudbury Regional High School 5-25-83
-
- jove_proc.c
-
- This file contains procedures to handle the shell to buffer commands
- and buffer to shell commands. It isn't especially neat, but I think
- it is understandable. */
-
- #include "jove.h"
- #ifdef UNIX
- #include "whoami.h"
- #include <signal.h>
- #endif
-
- extern int MakeAll; /* funcs.h */
- extern int WtOnMk; /* funcs.h */
-
-
- /*-------------------------o.s. dependent----------------------------*/
-
- #ifdef UNIX
-
- static char *MakeName();
-
- static char *cerrfmt = "\\([^:]*\\):\\([0-9][0-9]*\\):";
- /* C error scanf format string for errors of the form
- * filename:linenum: error message
- */
-
- static char *lerrfmt = "\"\\([^:]*\\)\", line \\([0-9][0-9]*\\):";
- /* Lint error for errors of the form
- * "filename", line linenum: error message.
- */
-
- struct error {
- BUFFER *er_buf; /* Buffer error is in */
- LINE *er_mess; /* Actual error message */
- LINE *er_text; /* Actual error */
- int er_char; /* char pos of error */
- struct error *er_next; /* List of error */
- };
-
- static struct error *thiserror = 0,
- *errorlist = 0;
- static BUFFER *thisbuf = 0; /* Buffer that error parsing took place */
-
-
-
- CParse()
- {
- ErrParse(cerrfmt);
- }
-
- LintParse()
- {
- ErrParse(lerrfmt);
- }
-
- /* Send the buffer to the spell program (for some reason, writing the
- file and running spell on that file caused spell to just sit there!)
- and then go find each occurrence of the mispelled words that the user
- says to go find. Check out SpParse() */
-
- SpellCom()
- {
- WINDOW *errwind,
- *savewind;
- char command[100];
-
- savewind = curwind;
- exp_p = 1;
- if (IsModified(curbuf))
- SaveFile();
-
- ignore(UnixToBuf("Spell", 1, !exp_p, "/bin/csh", "csh", "-cf",
- sprintf(command, "/bin/spell %s", curbuf->b_fname), 0));
- NotModified();
- Bof(); /* Beginning of (error messages) file */
- errwind = curwind;
- if (linebuf[0]) {
- SpParse(errwind, savewind);
- if (thiserror)
- NextError();
- message("Go get 'em");
- } else {
- message("No errors");
- SetWind(savewind);
- }
- }
-
- /* Go the the next error, if there is one. Put the error buffer in
- one window and the buffer with the error in another window.
- It checks to make sure that the error actually exists. */
-
- NextError()
- {
- register int i = exp;
-
- while (--i >= 0)
- DoNextErr();
- }
-
- /* Run make, first writing all the modified buffers (if the WtOnMk flag is
- * non-zero), parse the errors, and go the first error.
- */
-
- MakeErrors()
- {
- WINDOW *old = curwind;
- int status;
-
- if (WtOnMk)
- WtModBuf();
- if (MakeAll)
- status = UnixToBuf("make", 1, 1, "/bin/make", "Make", "-k", 0);
- else
- status = UnixToBuf("make", 1, 1, "/bin/make", "Make", 0);
- com_finish(status, "make");
- if (errorlist)
- ErrFree();
-
- if (status)
- #ifndef VMUNIX
- ErrParse(cerrfmt);
- #else
- ErrParse(lerrfmt);
- #endif VMUNIX
-
- if (thiserror)
- NextError();
- else
- SetWind(old);
- }
-
- ShellCom()
- {
- char command[100];
-
- strcpy(command, ask((char *) 0, FuncName()));
- DoShell(MakeName(command), command);
- }
-
- /* Run the command to bufname, erase the buffer if clobber is non-zero,
- * and redisplay if disp is non-zero.
- */
-
- /* VARARGS3 */
-
- UnixToBuf(bufname, disp, clobber, func, args)
- char *bufname,
- *func;
- {
- int p[2],
- pid;
- char buff[LBSIZE];
- extern int ninbuf;
-
- message("Starting up...");
- pop_wind(bufname, clobber);
- if (disp)
- redisplay();
- if (clobber)
- curbuf->b_type = SCRATCHBUF;
- exp = 1;
-
- dopipe(p);
- pid = fork();
- if (pid == -1) {
- PipeClose(p);
- complain("Cannot fork");
- }
- if (pid == 0) {
- ignorf(signal(SIGINT, SIG_DFL));
-
- ignore(close(0));
- ignore(open("/dev/null", 0));
- ignore(close(1));
- ignore(close(2));
- ignore(dup(p[1]));
- ignore(dup(p[1]));
- PipeClose(p);
- execv(func, (char **) &args);
- ignore(write(1, "Execl failed", 12));
- _exit(1);
- } else {
-
-
-
- int (*oldquit)() = signal(SIGINT, SIG_IGN);
-
- int status;
- char *mess;
-
- ignore(close(p[1]));
- io = p[0];
- while (getfline(buff) != EOF) {
- ins_str(buff);
- LineInsert();
- if (ninbuf <= 0) {
- #ifdef VMUNIX /* No easy way to find out */
- mess = "Chugging along...";
- #else
- #if defined(MENLO_JCL) && !defined(NONFP)
- {
- short avg[3];
- double theavg;
-
- ignore(gldav(avg));
- theavg = (double) avg[0] / 256;
- if (theavg < 1.0)
- mess = "Screaming along...";
- else if (theavg < 3.0)
- mess = "Chugging along...";
- else
- mess = "Crawling along...";
- }
- #else
- mess = "Chugging along...";
- #endif MENLO_JCL
- #endif VMUNIX
- message(mess);
- redisplay();
- }
- }
- UpdateMesg();
- IOclose();
-
-
-
- ignorf(signal(SIGINT, oldquit));
-
- while (wait(&status) != pid)
- ;
- return status;
- }
- return 0;
- }
-
- /* Send a region to shell. Now we can beautify C and sort programs */
-
- RegToShell()
- {
- char com[100];
- MARK *m = CurMark();
-
- strcpy(com, ask((char *) 0, FuncName()));
- if (!exp_p) {
- exp_p = 1; /* So it doesn't delete the region */
- exp = 0;
- }
- if (inorder(m->m_line, m->m_char, curline, curchar))
- RegToUnix(curbuf->b_name, 1, m->m_line, m->m_char,
- curline, curchar, com);
- else
- RegToUnix(curbuf->b_name, 1, curline, curchar, m->m_line,
- m->m_char, com);
- message("Done");
- }
-
- /* Add an error to the end of the list of errors. This is used for
- * parse-C/LINT-errors and for the spell-buffer command
- */
-
- static struct error *
- AddError(newerror, errline, buf, line, charpos)
- struct error *newerror;
- LINE *errline,
- *line;
- BUFFER *buf;
- {
- if (newerror) {
- newerror->er_next = (struct error *)
- emalloc(sizeof (struct error));
- newerror = newerror->er_next;
- } else
- thiserror = newerror = errorlist = (struct error *)
- emalloc(sizeof (struct error));
- newerror->er_buf = buf;
- newerror->er_text = line;
- newerror->er_char = charpos;
- newerror->er_next = 0;
- newerror->er_mess = errline;
- return newerror;
- }
-
- /* Returns the num'th line in buffer `b' */
-
- static LINE *
- LineAt(num, b)
- register int num;
- BUFFER *b;
- {
- register LINE *lp = b->b_zero;
-
- while (--num > 0 && lp)
- lp = lp->l_next;
- return lp;
- }
-
- /* Parse for C/LINT errors in the current buffer. Set up for the next-error
- command. */
-
- static ErrParse(fmtstr)
- char *fmtstr;
- {
- BUFLOC *bp;
- char fname[100],
- lineno[10];
- struct error *ep = 0;
- BUFFER *buf;
-
- Bof();
- if (errorlist)
- ErrFree();
- thisbuf = curbuf;
- /* Find a line with a number on it */
- while (bp = dosearch(fmtstr, 1, 1)) {
- SetDot(bp);
- putmatch(1, fname, sizeof fname);
- putmatch(2, lineno, sizeof lineno);
- buf = do_find((WINDOW *) 0, fname);
- ep = AddError(ep, curline, buf, LineAt(atoi(lineno), buf), 0);
- }
- }
-
-
- /* There is one word per line in the current buffer. Read that word
- and ask the user whether he wants us to search for it (if it is a
- big buffer he may not want to if he thinks it is spelled correctly). */
-
- static SpParse(err, buf)
- WINDOW *err,
- *buf;
- {
- BUFLOC *bp;
- char string[100],
- ans;
- struct error *newerr = 0;
-
- if (errorlist)
- ErrFree();
- thisbuf = err->w_bufp;
- SetWind(err);
- for (;;) {
- if (linebuf[0] == 0)
- goto nextword;
- s_mess("Is \"%s\" misspelled (Y or N)? ", linebuf);
- ignore(sprintf(string, "\\b%s\\b", linebuf));
- SetWind(buf); /* Paper buffer */
- Bof();
- do
- ans = getch();
- while ((ans = Upperc(ans)) != 'Y' && ans != 'N');
-
- if (ans == 'Y') { /* Not correct */
- while (bp = dosearch(string, 1, 1)) {
- SetDot(bp);
- newerr = AddError(newerr,
- thisbuf->b_dot, buf->w_bufp,
- curline, curchar);
- }
- }
-
- nextword:
- SetWind(err); /* Back to error window to move to
- the next word */
- if (eobp())
- break;
- if (ans == 'N') { /* Delete the word ... */
- Bol();
- DoTimes(KillEOL, 1); /* by deleting the line */
- } else {
- if (lastp(curline))
- break;
- else
- SetLine(curline->l_next);
- }
- }
- }
-
- /* Free up all the errors */
-
- static ErrFree()
- {
- register struct error *ep;
-
- for (ep = errorlist; ep; ep = ep->er_next)
- free((char *) ep);
- errorlist = thiserror = 0;
- }
-
-
- static DoNextErr()
- {
- /* Make sure we haven't deleted the line with the actual error
- by accident. */
-
- while (errorlist && thiserror) {
- if (inlist(thiserror->er_buf->b_zero, thiserror->er_text))
- break;
- thiserror = thiserror->er_next;
- }
- if (errorlist == 0 || thiserror == 0)
- complain("No errors");
-
- pop_wind(thisbuf->b_name, 0);
- SetLine(thiserror->er_mess);
- SetTop(curwind, (curwind->w_line = thiserror->er_mess));
- pop_wind(thiserror->er_buf->b_name, 0);
- DotTo(thiserror->er_text, thiserror->er_char);
- thiserror = thiserror->er_next;
- }
-
-
- /* Make a buffer name given the command `command', i.e. "fgrep -n foo *.c"
- will return the buffer name "fgrep". */
-
- static char *
- MakeName(command)
- char *command;
- {
- static char bufname[50];
- char *cp = bufname, c;
-
- while ((c = *command++) && (c == ' ' || c == '\t'))
- ;
- do
- *cp++ = c;
- while ((c = *command++) && (c != ' ' && c != '\t'));
- *cp = 0;
- cp = rindex(bufname, '/');
- if (cp)
- strcpy(bufname, cp + 1);
- return bufname;
- }
-
- ShToBuf()
- {
- char bufname[100];
-
- strcpy(bufname, ask((char *) 0, "Buffer: "));
- DoShell(bufname, ask((char *) 0, "Command: "));
- }
-
- /* Run the shell command into `bufname'. Empty the buffer except when we
- give a numeric argument, in which case it inserts the output at the
- current position in the buffer. */
-
- static DoShell(bufname, command)
- char *bufname,
- *command;
- {
- WINDOW *savewp = curwind;
- int status;
-
- exp = 1;
- status = UnixToBuf(bufname, 1, !exp_p, "/bin/csh", "csh", "-fc",
- command, 0);
- com_finish(status, command);
- SetWind(savewp);
- }
-
- static com_finish(status, com)
- char *com;
- {
- s_mess("\"%s\" completed %ssuccessfully", com, status ? "un" : "");
- }
-
- static dopipe(p)
- int p[];
- {
- if (pipe(p) == -1)
- complain("Cannot pipe");
- }
-
- static PipeClose(p)
- int p[];
- {
- ignore(close(p[0]));
- ignore(close(p[1]));
- }
-
- /* Writes the region to a tmp file and then run the command with input
- from that file */
-
- static RegToUnix(bufname, replace, line1, char1, line2, char2, func)
- char *bufname;
- LINE *line1,
- *line2;
- char *func;
- {
- char *fname = mktemp(TMPFILE);
- char com[100];
-
- if ((io = creat(fname, 0644)) == -1)
- complain(IOerr("create", fname));
- putreg(line1, char1, line2, char2);
- IOclose();
- if (replace)
- DelReg();
- ignore(sprintf(com, "%s < %s", func, fname));
- ignore(UnixToBuf(bufname, 0, 0, "/bin/csh", "csh", "-c", com, 0));
- ignore(unlink(fname));
- }
-
- #endif
-
- /* clone */
-
- /* end */